package libcore.util

import android.text.InputFilter
import android.text.Spanned
import android.text.TextUtils

/**
 * create by fuchaoyang
 * 配合 android:inputType="numberDecimal"
 * 限制输入的最多几位小数
 * 限制输入的最大值
 */
class NumberInputFilter
/**
 * @param maxValue 限制输入的最大值
 * @param decimalDigits 限制输入的最多几位小数
 * @param canEqualMax 是否可等于最大值
 */
@JvmOverloads
constructor(
  private val maxValue: Double = Double.MAX_VALUE,
  private val decimalDigits: Int,
  /** 是否可以=最大值  */
  private val canEqualMax: Boolean = true
) : InputFilter {
  /**
   * source	新输入的字符串
   * start	开始位置 ，source的start
   * end	结束位置 ，source的end，或理解为长度
   * dest	输入之前文本框内容
   * dstart	光标所在的位置
   * dend //当前的结束位置，要替换或者添加的终止始位置，若为选择一串字符串进行更改，则为选中字符串 最后一个字符在dest中的位置
   */
  override fun filter(
    source: CharSequence, start: Int, end: Int, dest: Spanned, dstart: Int,
    dend: Int
  ): CharSequence? {
    // 如果第一位是小数点，直接return
    if (TextUtils.isEmpty(source)) return null
    if ("." == source.toString()) return null
    // 获取小数点的位置
    var dotPos = -1
    val len = dest.length
    for (i in 0 until len) {
      if (dest[i] == '.') {
        dotPos = i
        break
      }
    }
    if (dotPos in 0 until dstart) { // 这里要判断光标的位置，如果光标在小数点之后，则不允许输入
      if (len - dotPos > decimalDigits) { // 限制输入的小数位数
        return ""
      }
    }

    // 计算数值
    val destText = dest.toString() // 原始字符串
    val first = destText.substring(0, dstart) // 光标之前的字符串
    val second = destText.substring(dstart) // 光标之后的字符串
    val sum = first + source.toString() + second // 输入之后的字符串
    // 如果新输入的长度>1，则再校验一次输入之后的小数位置
    if (source.length > 1) { // 有可能直接setText(多为小数）或者粘贴进来多为小数，判断小数点后面的位数
      // 再次校验输入之后的小数点是否符合
      for (i in sum.indices) {
        if (sum[i] == '.') {
          dotPos = i
          break
        }
      }
      if (dotPos >= 0 && sum.length - 1 - dotPos > decimalDigits) {
        // 裁剪
        return ""
      }
    }
    try {
      val sumText = sum.toDouble()
      if (sumText > maxValue || !canEqualMax && sumText == maxValue) { // 限制输入最大数值
        return ""
      }
    } catch (ex: NumberFormatException) {
      ex.printStackTrace()
      return "" // 如果输入的无效，也禁止
    }
    return null
  }

}